﻿using System;
using System.Collections.Generic;
using System.Text;
using Cn.Cellula.Biz.Port;
using Cn.Cellula.Model;
using System.Xml;
using System.Web.UI.WebControls;
using System.Reflection;
using Cn.Edwon.Spring;
using Cn.Cellula.Model.System;

namespace Cn.Cellula.Biz.Impl {
    class CategoryBiz:MyBizSupport,ICategoryBiz {
        private string GetCatalogPrefix(XmlNode n,string prefix) {
            string _prefix = "";
            n = n.ParentNode;
            while (n.Name != "root") {
                _prefix += prefix;
                n = n.ParentNode;
            }
            return _prefix;
        }
        private void DeleteCategory(String key,String rOwnerKey) {
            IList<TSysCategoryEO> list = null;
            String hql = "from TSysCategoryEO eo where eo.ParentId='" + key + "' and eo.OwnerKey='" + rOwnerKey + "'";
            list = base.Find<TSysCategoryEO>(hql);
            if (list != null && list.Count > 0) {
                throw new Exception("具有子节点的项(" + list[0].CategoryName + ")无法被删除");
            }
            hql = "from TSysCategoryEO eo where eo.CategoryId='" + key + "' and eo.OwnerKey='" + rOwnerKey + "'";
            base.Delete(hql);
        }

        #region ICategoryBiz 成员
        public String LoadCategory2JskitDdl(String rOwnerKey, String rTypeKey, String parentKey) {
            try {
                StringBuilder sb = new StringBuilder();
                XmlDocument doc = this.LoadCatalog2XHtml(rOwnerKey, rTypeKey, parentKey);
                XmlNodeList nl = doc.DocumentElement.ChildNodes;
                sb.Append("[");
                for (int i=0;i<nl.Count;i++){
                    XmlNode n = nl[i];
                    if (i > 0)
                        sb.Append(',');
                    sb.Append(ParseNode2JskitDdlItem(n));
                }
                sb.Append("]");
                return sb.ToString();
            } catch (Exception ex) {
                log.Error(ex.Message);
                return "[]";
            }
        }
        public String ParseNode2JskitDdlItem(XmlNode node) {
            StringBuilder sb = new StringBuilder();
            String id, alias,name;
            id = node.Attributes["id"].Value;
            alias = node.Attributes["alias"].Value;
            name = node.Attributes["name"].Value;
            sb.Append("[");
            sb.Append("\"" + id + "\"");
            sb.Append(",\"" + alias + "\"");
            sb.Append(",[");
            if (node.ChildNodes.Count > 0) {
                for (int i = 0; i < node.ChildNodes.Count; i++) {
                    if (i > 0)
                        sb.Append(",");
                    sb.Append(ParseNode2JskitDdlItem(node.ChildNodes[i]));
                }
            }
            sb.Append("]");
            sb.Append("]");
            return sb.ToString();
        }


        public String LoadCategory2Json(String rOwnerKey, String rTypeKey, String parentKey) {
            try {
                XmlDocument doc = this.LoadCatalog2XHtml(rOwnerKey,rTypeKey, parentKey);
                return ParseNode2Json(doc.DocumentElement);
            } catch (Exception ex) {
                log.Error(ex.Message);
                return "[]";
            }
        }

        public String ParseNode2Json(XmlNode node) {
            StringBuilder sb = new StringBuilder();
            String id, name, alias, parentId,picCount,coverPath,url;
            Int32 order = 0;
            if (node.Name == "root") {
                id = "root";
                name = "/";
                alias = "/";
                parentId = null;
                picCount = "0";
                coverPath = "";
                url = "";
            } else {
                id = node.Attributes["id"].Value;
                name = node.Attributes["name"].Value;
                alias = node.Attributes["alias"].Value;
                parentId = node.Attributes["parent"].Value;
                picCount = node.Attributes["pic_count"].Value;
                coverPath = node.Attributes["cover_path"].Value;
                url = node.Attributes["url"].Value;
                try {
                    order = Convert.ToInt32(node.Attributes["order"].Value);
                } catch { }
            }
            sb.Append("{");
            sb.Append("\"ParentId\":\"" + parentId + "\"");
            sb.Append(",\"Id\":\"" + id + "\"");
            sb.Append(",\"Name\":\"" + name + "\"");
            sb.Append(",\"Alias\":\"" + alias + "\"");
            sb.Append(",\"Order\":\"" + order + "\"");
            sb.Append(",\"PicCount\":\"" + picCount + "\"");
            sb.Append(",\"CoverPath\":\"" + coverPath + "\"");
            sb.Append(",\"Url\":\"" + url + "\"");
            sb.Append(",\"Children\":[");
            if (node.ChildNodes.Count > 0) {
                for (int i = 0; i < node.ChildNodes.Count; i++) {
                    if (i > 0)
                        sb.Append(",");
                    sb.Append(ParseNode2Json(node.ChildNodes[i]));
                }
            }
            sb.Append("]");
            sb.Append("}");
            return sb.ToString();
        }


        public IList<TSysCategoryEO> LoadCategories(String rOwnerKey, String rTypeKey, string parentKey) {
            String hql = "from TSysCategoryEO eo where eo.TypeKey='" + rTypeKey + "'";
            if (String.IsNullOrEmpty(parentKey)) {
                hql += " and eo.ParentId='' or eo.ParentId is null ";
            } else {
                hql += " and eo.ParentId='" + parentKey + "'";
            }

            if (!String.IsNullOrEmpty(rOwnerKey)) {
                hql += " and eo.OwnerKey='" + rOwnerKey + "' ";
            }

            return commonDao.Find<TSysCategoryEO>(hql);
        }

        public IList<ListItem> LoadCatalog2ListItem(String rOwnerKey, String rTypeKey, String rPrefix, String rSelfKey, Boolean rSelected) {
            XmlDocument doc = LoadCatalog2XHtml(rOwnerKey,rTypeKey,null);
            return LoadCatalog2ListItem(doc, rPrefix, rSelfKey,rSelected);
        }
        public IList<ListItem> LoadCatalog2ListItem(XmlDocument doc,String rPrefix,String rSelfKey,Boolean rSelected) {
            if (!String.IsNullOrEmpty(rSelfKey)) {
                XmlNode _selfNode = doc.DocumentElement.SelectSingleNode("//div[@id='" + rSelfKey + "']");
                if (_selfNode != null) {
                    _selfNode.ParentNode.RemoveChild(_selfNode);
                }
            }
            XmlNodeList nodes = doc.SelectNodes("//div");
            IList<ListItem> list = new List<ListItem>();
            if(!rSelected)
                list.Add(new ListItem("", ""));
            foreach (XmlElement n in nodes) {
                ListItem eo = new ListItem();
                eo.Value = n.Attributes["id"].Value;
                eo.Text = GetCatalogPrefix(n,rPrefix) + n.Attributes["alias"].Value;
                if (String.IsNullOrEmpty(eo.Text)) continue;
                list.Add(eo);
            }
            return list;
        }

        /// <summary>
        /// 获得所有子孙节点的ID集合
        /// </summary>
        /// <param name="rOwnerKey"></param>
        /// <param name="rTypeKey"></param>
        /// <param name="rKey"></param>
        /// <returns></returns>
        public IList<String> LoadDescendantsKeys(String rOwnerKey,String rTypeKey,String rKey) {
            XmlDocument doc = LoadCatalog2XHtml(rOwnerKey, rTypeKey, null);
            IList<String> list = new List<String>();
            if (String.IsNullOrEmpty(rKey)) return list;
            XmlNodeList nl = doc.SelectNodes("//div[@id='" + rKey + "']//div");
            if (nl != null) {
                foreach (XmlNode n in nl) {
                    list.Add(n.Attributes["id"].Value);
                }
            }
            return list;
        }

        public XmlDocument LoadCatalog2XHtml(String rOwnerKey, String rTypeKey, String rParentKey) {
            String hql = " from VSysCategoryEO eo where eo.CategoryName is not null ";
            if (!String.IsNullOrEmpty(rTypeKey)) {
                hql += " and eo.TypeKey='" + rTypeKey + "' ";
            }
            if (!String.IsNullOrEmpty(rOwnerKey)) {
                hql += " and eo.OwnerKey='" + rOwnerKey + "' ";
            }
            hql += " order by eo.TypeKey,eo.OrderNumber desc,eo.CategoryName ";
            IList<VSysCategoryEO> list = base.Find<VSysCategoryEO>(hql);
            //启动一个空的xmlDocument对象
            XmlDocument dom = new XmlDocument();
            dom.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?><root></root>");
            XmlElement root = dom.DocumentElement;
            //将catalog全部装入Dom对象
            if (list != null && list.Count > 0) {
                foreach (VSysCategoryEO eo in list) {
                    XmlElement node = dom.CreateElement("div");
                    node.SetAttribute("id", eo.CategoryId);
                    node.SetAttribute("layer", "0");
                    node.SetAttribute("alias", eo.CategoryAlias);
                    node.SetAttribute("pic_count", eo.PicCount + "");
                    node.SetAttribute("cover_path", eo.CoverPath);
                    node.SetAttribute("url", eo.Url);
                    if (String.IsNullOrEmpty(eo.ParentId)) {
                        node.SetAttribute("parent", "");
                    } else {
                        node.SetAttribute("parent", eo.ParentId);
                    }
                    node.SetAttribute("name", eo.CategoryName);
                    node.SetAttribute("order", eo.OrderNumber + "");
                    root.AppendChild(node);
                }
                //按照父子关系移动节点对象
                XmlNodeList nodes = root.ChildNodes;
                //Int32 _parentLayer = 0;
                foreach (VSysCategoryEO eo in list) {
                    if (String.IsNullOrEmpty(eo.ParentId)) continue;
                    XmlNode n = root.SelectSingleNode("//div[@id='" + eo.CategoryId + "']");
                    XmlNode p = root.SelectSingleNode("//div[@id='" + eo.ParentId + "']");
                    if (n != null && p != null) {
                        p.AppendChild(n);
                    } else {
                        n.ParentNode.RemoveChild(n);
                    }
                }
                if (!String.IsNullOrEmpty(rParentKey)) {
                    XmlNode p = root.SelectSingleNode("//div[@id='" + rParentKey + "']");
                    XmlNode pclone = p.Clone();
                    root.RemoveAll();
                    root.AppendChild(pclone);
                }
            }
            return dom;
        }

        public IList<TSysCategoryEO> LoadCategoryPath(XmlDocument doc, String rCategoryId) {
            IList<TSysCategoryEO> list = new List<TSysCategoryEO>();
            XmlNode _selfNode = doc.DocumentElement.SelectSingleNode("//div[@id='" + rCategoryId + "']");
            while (_selfNode != null && _selfNode.Name != "root") {
                TSysCategoryEO eo = new TSysCategoryEO();
                eo.CategoryId = _selfNode.Attributes["id"].Value;
                eo.CategoryName = _selfNode.Attributes["name"].Value;
                eo.CategoryAlias = _selfNode.Attributes["alias"].Value;
                eo.ParentId = _selfNode.Attributes["parent"].Value;
                list.Add(eo);
                _selfNode = _selfNode.ParentNode;
            }
            return list;
        }
        public IList<TSysCategoryEO> LoadCategoryPath(String rOwnerKey, String rTypeKey, String rCategoryId) {
            XmlDocument doc = LoadCatalog2XHtml(rOwnerKey, rTypeKey, null);
            IList<TSysCategoryEO> list = new List<TSysCategoryEO>();
            XmlNode _selfNode = doc.DocumentElement.SelectSingleNode("//div[@id='" + rCategoryId + "']");
            while (_selfNode != null && _selfNode.Name != "root") {
                TSysCategoryEO eo = new TSysCategoryEO();
                eo.CategoryId = _selfNode.Attributes["id"].Value;
                eo.CategoryName = _selfNode.Attributes["name"].Value;
                eo.CategoryAlias = _selfNode.Attributes["alias"].Value;
                eo.ParentId = _selfNode.Attributes["parent"].Value;
                list.Add(eo);
                _selfNode = _selfNode.ParentNode;
            }
            return list;
        }
        public String LoadCategoryPath(String rOwnerKey, String rTypeKey, String rCategoryId, String rSeparate) {
            XmlDocument doc = LoadCatalog2XHtml(rOwnerKey, rTypeKey, null);
            String path = "";
            XmlNode _selfNode = doc.DocumentElement.SelectSingleNode("//div[@id='" + rCategoryId + "']");
            while (_selfNode != null && _selfNode.Name != "root") {
                if(path=="")
                    path = _selfNode.Attributes["alias"].Value;
                else
                    path = _selfNode.Attributes["alias"].Value + rSeparate + path;
                _selfNode = _selfNode.ParentNode;
            }
            return path;
        }


        public void DeleteCategories(string[] rKeys, String rOwnerKey) {
            for (int i = 0; i < rKeys.Length; i++) {
                DeleteCategory(rKeys[i],rOwnerKey);
            }
        }

        public void DeleteCategories(IList<string> rKeys,String rOwnerKey) {
            foreach (String k in rKeys) {
                DeleteCategory(k, rOwnerKey);
            }
        }

        public TSysCategoryEO LoadByName(String rName, String rTypeKey,String rOwnerKey) {
            String hql = " from TSysCategoryEO eo where eo.CategoryName='" + rName + "' and eo.TypeKey='"+rTypeKey+"'  and eo.OwnerKey='" + rOwnerKey + "'";
            IList<TSysCategoryEO> list = base.Find<TSysCategoryEO>(hql);
            if (list != null && list.Count > 0)
                return list[0];
            else
                return null;
        }
        private int GetNodeDirection(XmlElement rNode) {
            int layers = 1;
            XmlNode node = (XmlNode)rNode;
            while (node.Name != "root") {
                node = node.ParentNode;
                layers++;
            }
            return (layers % 2 == 0) ? 2 : 1;
        }
        private int GetNodeLocation(int direction) {
            return (direction == 1) ? 2 : 3;
        }
        public string LoadCategory2JskitMenuXml(String rTypeKey,String rUrl,Boolean rAllOption,String rAllText) {
            String hql = "";
            if (rUrl == null) rUrl = "#";
            XmlDocument dom = new XmlDocument();
            dom.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?><root></root>");
            XmlElement root = dom.DocumentElement;
            root.SetAttribute("id", "root");
            if (rAllOption) {
                XmlElement node = dom.CreateElement("div");
                node.SetAttribute("type", "jmnode");
                node.SetAttribute("id", Guid.NewGuid().ToString());
                node.SetAttribute("target", "_self");
                node.SetAttribute("css", "jskitcategory_item_all");
                node.SetAttribute("url", rUrl.Replace("$ID", ""));
                node.SetAttribute("name", rAllText);
                root.AppendChild(node);
            }
            hql = " from VSysCategoryEO eo where eo.TypeKey='" + rTypeKey + "' order by eo.OrderNumber desc,eo.CategoryAlias ";
            IList<VSysCategoryEO> list = base.Find<VSysCategoryEO>(hql);
            String pk = Guid.NewGuid().ToString();
            //将catalog全部装入Dom对象
            foreach (VSysCategoryEO eo in list) {
                XmlElement node = dom.CreateElement("div");
                node.SetAttribute("type", "jmnode");
                node.SetAttribute("id", pk+eo.CategoryId);
                node.SetAttribute("target", "_self");
                if (String.IsNullOrEmpty(eo.ParentId)) {
                    node.SetAttribute("css", "jskitcategory_item_f");
                } else {
                    node.SetAttribute("css", "jskitcategory_item");
                }
                node.SetAttribute("url", rUrl.Replace("$ID",eo.CategoryId));
                node.SetAttribute("name", eo.CategoryAlias);
                root.AppendChild(node);
                int direct = GetNodeDirection(node);
                node.SetAttribute("direction", direct + "");
                node.SetAttribute("location", GetNodeLocation(direct) + "");
            }
            //按照父子关系移动节点对象
            XmlNodeList nodes = root.ChildNodes;
            //Int32 _parentLayer = 0;
            foreach (VSysCategoryEO eo in list) {
                if (String.IsNullOrEmpty(eo.ParentId)) continue;
                XmlNode n = root.SelectSingleNode("//div[@id='" + pk + eo.CategoryId + "']");
                if (n == null) continue;
                XmlNode p = root.SelectSingleNode("//div[@id='" + pk + eo.ParentId + "']");
                if (p != null) {
                    p.Attributes["url"].Value = "";
                    p.AppendChild(n);
                } else {
                    n.ParentNode.RemoveChild(n);
                }
            }
            return dom.InnerXml;
        }

        #endregion

    }
}
